import { VuexModule, Module, Mutation, Action, getModule } from 'vuex-module-decorators'
import { RouteConfig } from 'vue-router'
import { asyncRoutes, constantRoutes } from '@/router'
import store from '@/store'
import { resolve } from 'path'
import { rejects } from 'assert'

function hasPermission(permission:any, route: any) {
  if (route.meta && route.meta.permission) {
    return permission.some((role:any) => route.meta.permission.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes:any, permission:any) {
  const res:any = []

  routes.forEach((route:any) => {
    const tmp = { ...route }
    if (hasPermission(permission, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, permission)
      }
      res.push(tmp)
    }
  })

  return res
}

export interface IPermissionState {
  routes: RouteConfig[]
  dynamicRoutes: RouteConfig[]
}

@Module({ dynamic: true, store, name: 'permission' })
class Permission extends VuexModule implements IPermissionState {
  public routes: RouteConfig[] = []
  public dynamicRoutes: RouteConfig[] = []

  @Mutation
  private SET_ROUTES(routes: RouteConfig[]) {
    this.routes = constantRoutes.concat(routes)
    this.dynamicRoutes = routes
  }

  @Action
  public GenerateRoutes(permissions: string[]) {
    return new Promise((resolve, reject)=>{

      let accessedRoutes = filterAsyncRoutes(asyncRoutes, permissions)
      
      this.SET_ROUTES(accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export const PermissionModule = getModule(Permission)
